package com.geekhalo.lego.plugin.lazyloader;

import com.geekhalo.lego.plugin.support.template.CreateClassContext;
import org.jetbrains.annotations.NotNull;

import java.util.List;

public class LazyLoaderTemplate {
    private static final String TEMPLATE_1 =
            "package {pkg};\n" +
            "\n" +
            "import com.geekhalo.lego.annotation.loader.LazyLoadBy;\n" +
            "\n" +
            "import java.lang.annotation.ElementType;\n" +
            "import java.lang.annotation.Retention;\n" +
            "import java.lang.annotation.RetentionPolicy;\n" +
            "import java.lang.annotation.Target;\n" +
            "\n" +
            "import static {pkg}.{className}.BEAN_NAME;\n" +
            "\n" +
            "@Target({ElementType.METHOD, ElementType.FIELD})\n" +
            "@Retention(RetentionPolicy.RUNTIME)\n";

    private static final String TEMPLATE_2 =
            "@LazyLoadBy(\"#{@\"+ BEAN_NAME +\".{loadMethodName}({paramStr})}\")\n" +
            "public @interface {className} {\n" +
            "    String BEAN_NAME = \"{beanName}\";\n" +
            "{methodStr}" +
            "}\n";

    public static String createShowView(CreateLazyLoaderContext context){
        return doReplace(TEMPLATE_2, context);
    }

    public static String create(CreateLazyLoaderContext context){
        return doReplace(TEMPLATE_1 + TEMPLATE_2, context);
    }

    @NotNull
    private static String doReplace(String content, CreateLazyLoaderContext context) {
        content = content.replace("{pkg}", context.getPkg());
        content = content.replace("{className}", context.getClsName());
        content = content.replace("{beanName}", context.getBeanName());
        content = content.replace("{loadMethodName}", context.getLoadMethodName());

        String paramStr = createParameters(context.getParameters());
        content = content.replace("{paramStr}", paramStr);

        String methodStr = createMethods(context.getParameters());
        content = content.replace("{methodStr}", methodStr);

        return content;
    }

    public static String createMethods(List<String> parameters){
        StringBuilder stringBuilder = new StringBuilder();
        for (String param : parameters){
            stringBuilder.append("    String " + param +"();\n");
            stringBuilder.append("\n");
        }
        return stringBuilder.toString();
    }

    private static String createParameters(List<String> parameters){
        StringBuilder stringBuilder = new StringBuilder();
        for (String param : parameters){
            stringBuilder.append("${");
            stringBuilder.append(param);
            stringBuilder.append("}");
            stringBuilder.append(", ");
        }
        stringBuilder.delete(stringBuilder.length()-2, stringBuilder.length());
        return stringBuilder.toString();
    }

    public static class CreateLazyLoaderContext extends CreateClassContext {
        private String beanName;
        private List<String> parameters;
        private String loadMethodName;
        public CreateLazyLoaderContext(String pkg, String clsName) {
            super(pkg, clsName);
        }

        public String getBeanName() {
            return beanName;
        }

        public void setBeanName(String beanName) {
            this.beanName = beanName;
        }

        public List<String> getParameters() {
            return parameters;
        }

        public void setParameters(List<String> parameters) {
            this.parameters = parameters;
        }

        public String getLoadMethodName() {
            return loadMethodName;
        }

        public void setLoadMethodName(String loadMethodName) {
            this.loadMethodName = loadMethodName;
        }
    }
}
